package com.vogue.flowmeter.ui.fragment;

import android.Manifest;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.vogue.flowmeter.R;
import com.vogue.flowmeter.ui.activity.AboutActivity;
import com.vogue.flowmeter.ui.activity.MainActivity;
import com.vogue.flowmeter.ui.activity.UnauthorizedActivity;
import com.vogue.flowmeter.ui.adapter.DeviceListAdapter;
import com.vogue.flowmeter.ui.adapter.ExtendedBluetoothDevice;

import java.util.List;
import java.util.Set;

import no.nordicsemi.android.support.v18.scanner.BluetoothLeScannerCompat;
import no.nordicsemi.android.support.v18.scanner.ScanCallback;
import no.nordicsemi.android.support.v18.scanner.ScanResult;
import no.nordicsemi.android.support.v18.scanner.ScanSettings;

/**
 * 设备
 */
public class HomeFragment extends BaseFragment implements ListView.OnItemClickListener {

    private ProgressBar stateScanning;
    private ObjectAnimator animator;
    private FloatingActionButton floatingActionButton;
    private final static long SCAN_DURATION = 5000;//扫描持续时间
    private final Handler handler = new Handler();
    private boolean scanning = false;
    private BluetoothAdapter bluetoothAdapter;
    private DeviceListAdapter adapter;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final BluetoothManager manager = (BluetoothManager) requireContext().getSystemService(Context.BLUETOOTH_SERVICE);
        if (manager != null) {
            bluetoothAdapter = manager.getAdapter();
        }
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        stateScanning=root.findViewById(R.id.state_scanning);

        floatingActionButton=root.findViewById(R.id.floatingActionButton);
        final ListView listview =root.findViewById(R.id.ble_devices);
        listview.setEmptyView(root.findViewById(android.R.id.empty));
        listview.setAdapter(adapter = new DeviceListAdapter());
        listview.setOnItemClickListener(this);


        addBoundDevices();
        startScan();

        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!scanning){
                    startScan();
                }else {
                    showToast("前面的扫描还在继续，请稍后");
                }
            }
        });


        return root;
    }
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.home_top_nav_menu,menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.home_navigation_settings:
                showToast("设置没有开发");
                break;
            case R.id.home_navigation_unauthorized:
                startActivity(new Intent(this.getContext(), UnauthorizedActivity.class));
                break;
            case R.id.home_navigation_about:
                startActivity(new Intent(this.getContext(), AboutActivity.class));
                break;
            default:
                return false;

        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        stopScan();
        final ExtendedBluetoothDevice extendedBluetoothDevice = (ExtendedBluetoothDevice) adapter.getItem(position);
        ((MainActivity)requireActivity()).onConnection(extendedBluetoothDevice.getDevice());

    }

    @Override
    public void onDestroy() {
        stopScan();
        super.onDestroy();
    }
    public void startBannerLoadingAnim() {
        stateScanning.setVisibility(View.VISIBLE);
        floatingActionButton.setImageResource(R.drawable.ic_loading);
        animator = ObjectAnimator.ofFloat(floatingActionButton, "rotation", 0, 360);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setDuration(800);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

    public void stopBannerLoadingAnim() {
        stateScanning.setVisibility(View.GONE);
        floatingActionButton.setImageResource(R.drawable.ic_bluetooth_searching);
        animator.cancel();
        floatingActionButton.setRotation(0);
    }

    /**
     *扫描5秒，然后在发现BluetoothLE设备时停止扫描，然后重新扫描
     *激活后，将对自定义BLE服务UUID执行常规扫描，然后筛选出。
     *使用类ScannerServiceParser
     */
    private void startScan() {
        startBannerLoadingAnim();
        //从Android 6.0开始我们需要获得Manifest.permission.ACCESS_FINE_LOCATION 权限才能够扫描蓝牙设备。这与作为接近装置的信标有关。
        RxPermissions rxPermissions=new RxPermissions(this.getActivity());
        rxPermissions
                .request(Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.BLUETOOTH_ADMIN,Manifest.permission.BLUETOOTH)
                .subscribe(granted -> {
                    if (granted) {
                        adapter.clearDevices();
                        final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
                        final ScanSettings settings = new ScanSettings.Builder()
                                .setLegacy(false)
                                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                                .setReportDelay(1000)
                                .setUseHardwareBatchingIfSupported(false).build();
/*                        final List<ScanFilter> filters = new ArrayList<>();
                        filters.add(new ScanFilter.Builder().setServiceUuid(uuid).build());*/
                        scanner.startScan(null, settings, scanCallback);
                        scanning = true;
                        handler.postDelayed(() -> {
                            stopScan();
                        }, SCAN_DURATION);

                    } else {
                        showToast("您拒绝了授权");
                        scanning = false;
                    }
                });

    }

    /**
     * 停止扫描
     */
    private void stopScan() {
        stopBannerLoadingAnim();
        if (scanning) {
            stateScanning.setVisibility(View.GONE);
            final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
            scanner.stopScan(scanCallback);
            scanning = false;
        }
    }

    /**
     * 扫描回调
     */
    private ScanCallback scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(final int callbackType, @NonNull final ScanResult result) {
            // do nothing

        }

        @Override
        public void onBatchScanResults(@NonNull final List<ScanResult> results) {
            adapter.update(results);
        }

        @Override
        public void onScanFailed(final int errorCode) {
            // should never be called
            showToast("扫描失败");
            stopScan();
        }
    };

    private void addBoundDevices() {
        final Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
        adapter.addBondedDevices(devices);
    }
    /**
     *
     * @param msg
     */
    protected void showToast(String msg){
        if (true){
            requireActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(requireActivity(),msg,Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}